"""
定时任务模型
类似xxl-job-admin的任务管理功能
"""
from sqlalchemy import Column, String, Text, Boolean, DateTime, Integer, JSON, ForeignKey
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.sql import func
from sqlalchemy.orm import relationship
from app.database.base import Base
import uuid
from enum import Enum


class JobStatus(str, Enum):
    """任务状态枚举"""
    ACTIVE = "active"      # 激活状态
    INACTIVE = "inactive"  # 停用状态
    RUNNING = "running"    # 运行中
    PAUSED = "paused"      # 暂停状态


class JobType(str, Enum):
    """任务类型枚举"""
    CRON = "cron"          # CRON表达式任务
    INTERVAL = "interval"  # 间隔任务
    DATE = "date"          # 定时任务（单次）


class TriggerType(str, Enum):
    """触发器类型枚举"""
    MANUAL = "manual"      # 手动触发
    AUTO = "auto"          # 自动触发
    API = "api"            # API触发


class ScheduledJob(Base):
    """定时任务表"""
    __tablename__ = "scheduled_jobs"
    
    # 基础字段
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    job_name = Column(String(100), nullable=False, unique=True, comment="任务名称")
    job_group = Column(String(50), default="DEFAULT", comment="任务分组")
    description = Column(Text, comment="任务描述")
    
    # 任务配置
    job_type = Column(String(20), default=JobType.CRON, comment="任务类型")
    job_status = Column(String(20), default=JobStatus.INACTIVE, comment="任务状态")
    
    # 执行配置
    executor_handler = Column(String(200), nullable=False, comment="执行器处理器")
    executor_params = Column(JSON, comment="执行器参数")
    
    # 调度配置
    cron_expression = Column(String(100), comment="CRON表达式")
    interval_seconds = Column(Integer, comment="间隔秒数")
    start_time = Column(DateTime(timezone=True), comment="开始时间")
    end_time = Column(DateTime(timezone=True), comment="结束时间")
    
    # 执行配置
    timeout_seconds = Column(Integer, default=0, comment="超时时间(秒,0表示无限制)")
    retry_count = Column(Integer, default=0, comment="重试次数")
    retry_interval = Column(Integer, default=30, comment="重试间隔(秒)")
    
    # 路由策略
    route_strategy = Column(String(50), default="FIRST", comment="路由策略")
    executor_block_strategy = Column(String(50), default="SERIAL_EXECUTION", comment="阻塞处理策略")
    
    # 分片配置
    enable_sharding = Column(Boolean, default=False, comment="是否启用分片")
    shard_count = Column(Integer, default=1, comment="分片数量")
    shard_strategy = Column(String(50), default="hash", comment="分片策略")
    max_shard_nodes = Column(Integer, default=10, comment="最大分片节点数")
    
    # 负责人信息
    author = Column(String(100), comment="负责人")
    alarm_email = Column(String(500), comment="报警邮件")
    
    # 系统字段
    is_active = Column(Boolean, default=True, comment="是否启用")
    created_at = Column(DateTime(timezone=True), server_default=func.now(), comment="创建时间")
    updated_at = Column(DateTime(timezone=True), onupdate=func.now(), comment="更新时间")
    created_by = Column(UUID(as_uuid=True), comment="创建人")
    updated_by = Column(UUID(as_uuid=True), comment="更新人")
    
    # 关联关系
    job_logs = relationship("JobLog", back_populates="job", cascade="all, delete-orphan")


class JobLog(Base):
    """任务执行日志表"""
    __tablename__ = "job_logs"
    
    # 基础字段
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    job_id = Column(UUID(as_uuid=True), ForeignKey("scheduled_jobs.id"), nullable=False, comment="任务ID")
    
    # 执行信息
    trigger_type = Column(String(20), default=TriggerType.AUTO, comment="触发类型")
    trigger_time = Column(DateTime(timezone=True), server_default=func.now(), comment="触发时间")
    start_time = Column(DateTime(timezone=True), comment="开始执行时间")
    end_time = Column(DateTime(timezone=True), comment="结束执行时间")
    
    # 执行结果
    status = Column(String(20), comment="执行状态: SUCCESS, FAILED, TIMEOUT, RUNNING")
    result_code = Column(Integer, default=0, comment="执行结果码")
    result_msg = Column(Text, comment="执行结果信息")
    
    # 执行详情
    executor_address = Column(String(200), comment="执行器地址")
    executor_handler = Column(String(200), comment="执行器处理器")
    executor_params = Column(JSON, comment="执行器参数")
    executor_sharding_param = Column(String(20), comment="分片参数")
    executor_fail_retry_count = Column(Integer, default=0, comment="失败重试次数")
    
    # 执行日志
    process_log = Column(Text, comment="执行过程日志")
    error_log = Column(Text, comment="错误日志")
    
    # 关联关系
    job = relationship("ScheduledJob", back_populates="job_logs")


class JobGroup(Base):
    """任务分组表"""
    __tablename__ = "job_groups"
    
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    group_name = Column(String(50), nullable=False, unique=True, comment="分组名称")
    title = Column(String(100), nullable=False, comment="分组标题")
    description = Column(Text, comment="分组描述")
    
    # 执行器配置
    address_type = Column(Integer, default=0, comment="注册方式: 0=自动注册, 1=手动录入")
    address_list = Column(Text, comment="机器地址列表，多地址逗号分隔")
    
    # 系统字段
    is_active = Column(Boolean, default=True, comment="是否启用")
    created_at = Column(DateTime(timezone=True), server_default=func.now(), comment="创建时间")
    updated_at = Column(DateTime(timezone=True), onupdate=func.now(), comment="更新时间")


class JobRegistry(Base):
    """执行器注册表"""
    __tablename__ = "job_registries"
    
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    registry_group = Column(String(50), nullable=False, comment="执行器AppName")
    registry_key = Column(String(200), nullable=False, comment="执行器地址")
    registry_value = Column(String(500), nullable=False, comment="执行器地址")
    
    # 系统字段
    update_time = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), comment="更新时间")
    
    # 索引
    __table_args__ = (
        {"comment": "执行器注册表"}
    )